<?php
class ujn {

	static function loadClass($class_name, $path = '') {
		$cls_files = array();
		switch(strtolower(substr($class_name, 0, 4))) {	//可以自定义大小写名字
			case 'ujn_':
				$class_name = str_replace('_', DS, str_replace('ujn_', '', $class_name));

				if(!empty($path))
					$cls_files[] = $path . str_replace('_', DS, $class_name) . '.php';

				$cls_files[] = UJN_PATH . 'classes/' . $class_name . '.php';
				break;
			case 'mdl_':
				$class_name = str_replace('_', DS, str_replace(array('mdl_', 'Mdl_'), '', $class_name));

				$cls_files[] = UJN_PATH . 'models/' . $class_name . '.php';

				$custom_models_path = ujn::getCFG('models_path');
				if(!empty($custom_models_path)) {
					$cls_files[] = ujn::getCFG('models_path') . $class_name . '.php';
				}
				break;
			case 'tls_':
				$cls_files[] = UJN_PATH . 'tools/' . str_replace('_', DS, str_replace('tls_', '', $class_name)) . '.php';
				break;
			default:
				$controller_class_path = realpath($path . str_replace('_', DS, $class_name) . '.php');
				if('' == $controller_class_path) {
					function_exists('page_404') ? page_404($class_name, $path) : print('unfound class file: ' . $class_name . ' | ' . $path . str_replace('_', DS, $class_name) . '.php');
					exit;
				}
				$cls_files[] = $controller_class_path;
		}

		$loaded = false;
		foreach($cls_files as $cls_file) {
			if(!is_file($cls_file)) continue;

			include_once $cls_file;
			$loaded = true;
			break;
		}
	}

	static $_CFG = array();
	static function bindCFG($cfg) {
		if(is_array($cfg) && !empty($cfg)) {
			ujn::$_CFG = array_merge(ujn::$_CFG, $cfg);
		}
	}
	static function getCFG($name) {
		if(isset(ujn::$_CFG[$name])) {
			return ujn::$_CFG[$name];
		} else {

			$names = explode('.', $name);
			if(empty($names)) return false;

			$_cfg = ujn::$_CFG;
			$is_false = false;
			foreach($names as $n) {
				if(!isset($_cfg[$n])) $is_false = true;
				else $_cfg = $_cfg[$n];
			}

			if($is_false && defined('CUSTOM_CFG_PATH')) {
				$cfg_file = CUSTOM_CFG_PATH . str_replace('.', '/', $name) . '.php';
				if(is_file($cfg_file)) {
					$_cfg = require_once $cfg_file;
					$_cfgx = $_cfg;
					foreach(array_reverse($names) as $n) {
						$_cfgx = array( $n => $_cfgx );
					}

					$is_false = false;
					ujn::bindCFG($_cfgx);
				}
			}

			return $is_false ? false : $_cfg;
		}
	}

	static function runApplication($cfg, $function_name = '') {
		ujn::bindCFG(require_once UJN_PATH . 'default_cfgs.php');
		ujn::bindCFG($cfg);

		function_exists('ujn_session_start') && ujn_session_start();

		$view_name = '';
		if('' != $function_name) {

			$controller_object = new ujn_controller();

			function_exists('__func_before') && $controller_object = __func_before($controller_object);
			if(function_exists($function_name)) {

				$controller_object = call_user_func($function_name, $controller_object);
				$view_name = $function_name;
			} else die('unfound function ' . $function_name);
			function_exists('__func_after') && $controller_object = __func_after($controller_object);

		} else if(defined('USERPC')) {


			// This is not a JSON-RPC request
			if ( $_SERVER['REQUEST_METHOD'] != 'POST' || !isset($_SERVER['CONTENT_TYPE']) || $_SERVER['CONTENT_TYPE'] != 'application/json' ) return false;

			// reads the input data
			$request = json_decode(file_get_contents('php://input'),true);

//			// executes the task on local object
//			try {
//				if ($result = @call_user_func_array(array($object,$request['method']),$request['params'])) {
//					$response = array (
//                                    'id' => $request['id'],
//                                    'result' => $result,
//                                    'error' => NULL
//                                    );
//            } else {
//                $response = array (
//                                    'id' => $request['id'],
//                                    'result' => NULL,
//                                    'error' => 'unknown method or incorrect parameters'
//                                    );
//            }
//        } catch (Exception $e) {
//            $response = array (
//                                'id' => $request['id'],
//                                'result' => NULL,
//                                'error' => $e->getMessage()
//                                );
//        }
//
//        // output the response
//        if (!empty($request['id'])) { // notifications don't want response
//            header('content-type: text/javascript');
//            echo json_encode($response);
//        }
//
//        // finish
//        return true;



//			$controller_object = null;
//
//			$arr = isset( $cfg['amfArr'] ) ? $cfg['amfArr'] : tls_amf::parseRequest();
//			if(!class_exists($arr['controller'], false)) {
//				ujn::loadClass($arr['controller'], ujn::getCFG('controllers_path') . '/');
//				if(!class_exists($arr['controller'], false)) die('unfound controller class ' . $arr['controller']);
//			}
//
//			$c = new $arr['controller'];
////			method_exists($c, '_before')					&& call_user_func_array(array($c, '_before'), array( $arr['data'] ));
//			$data = method_exists($c, $arr['action'])		? call_user_func_array(array($c, $arr['action']), array( $arr['data'] )) : array();
////			$data = method_exists($c, '_after')			? call_user_func_array(array($c, '_after'), array( $arr['data'], $data )) : $data;
//			echo tls_amf::parseResponse($arr['responseURI'], $data);
//			exit();
		} else if(defined('USEAMF')) {
			$controller_object = null;

			$arr = isset( $cfg['amfArr'] ) ? $cfg['amfArr'] : tls_amf::parseRequest();
			if(!class_exists($arr['controller'], false)) {
				ujn::loadClass($arr['controller'], ujn::getCFG('controllers_path') . '/');
				if(!class_exists($arr['controller'], false)) die('unfound controller class ' . $arr['controller']);
			}

			$c = new $arr['controller'];
//			method_exists($c, '_before')					&& call_user_func_array(array($c, '_before'), array( $arr['data'] ));
			$data = method_exists($c, $arr['action'])		? call_user_func_array(array($c, $arr['action']), array( $arr['data'] )) : array();
//			$data = method_exists($c, '_after')			? call_user_func_array(array($c, '_after'), array( $arr['data'], $data )) : $data;
			echo tls_amf::parseResponse($arr['responseURI'], $data);
			exit();
		} else {	//前台访问的地址格式：	?controller-action?passs=value&p=v&p=v

			// @TODO: 404 地址自定义
			list($uri, $params)							= array_pad(explode('?', $_SERVER['QUERY_STRING'], 2), 2, '');
			list($controller_class_name, $action_name)	= array_pad(explode('-', $uri, 2), 2, '');

			parse_str($params, $_TMP_REQUEST);
			$_REQUEST = array_merge($_REQUEST, $_TMP_REQUEST);

			$controller_class_name	= '' == $controller_class_name ? ujn::getCFG('default_controllers_name') : $controller_class_name;
			$action_name			= '' == $action_name ? ujn::getCFG('default_action_name') : $action_name;

			list($unset_prefix) = explode('=', $params, 2);
			unset(
				$_REQUEST["{$controller_class_name}-{$action_name}?{$unset_prefix}"],
				$_REQUEST["{$controller_class_name}-{$action_name}?"],
				$_REQUEST["{$controller_class_name}-{$action_name}"],
				$_REQUEST["-{$action_name}"],
				$_REQUEST[$controller_class_name], $_GET[$controller_class_name],
				$_REQUEST[$action_name], $_GET[$action_name]
			);

			ujn::loadClass($controller_class_name, ujn::getCFG('controllers_path') . '/');
			if(!class_exists($controller_class_name, false)) die('unfound controller class ' . $controller_class_name);

			$controller_object	= new $controller_class_name;
			if(!method_exists($controller_object, $action_name) && $controller_object->show_action_error == true) die('unfound action method ' . $action_name);

			ujn_runtime::setParam('controller_class_name', $controller_class_name);
			ujn_runtime::setParam('action_name', $action_name);

			call_user_func_array(array($controller_object, '_before'), array());
			call_user_func_array(array($controller_object, $action_name), array());
			call_user_func_array(array($controller_object, '_after'), array());

			$view_name = $action_name;
		}

		ujn_runtime::setParam('controller_object', $controller_object);

		if(!is_null($controller_object) && isset($controller_object->auto_render) && $controller_object->auto_render) {
			ujn_view::dispatch($controller_object, $view_name);
		}
	}
}